package com.changgou.seckill.task;

import com.changgou.common.pojo.IdWorker;
import com.changgou.common.pojo.SeckillStatus;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.dao.SeckillOrderMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author tu zy
 * @version 1.0
 * @date 2021/7/21 22:16
 */

@Component
public class MultiThreadingCreadingCreateorder {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillOrderMapper seckillOrderMapper;

    @Autowired
    private IdWorker idWorker;


    /**
     * 异步执行
     * @Async:该方法会异步执行（底层多线程方式）
     */
    @Async
    public void createOrder(){

        try {

            System.out.println("多线程执行开始");
            Thread.sleep(10000);
            System.out.println("多线程执行结束");



            //从redis队列中获取用户排队信息
            SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();


            if (seckillStatus==null){
                return;
            }

            String username =seckillStatus.getUsername();
            //先到SeckillGoodsCountList_ID队列中获取该商品的一个信息，如果能获取，则可以下单
            Object sgoods = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();
            //如果不能获取该商品的队列信息，则表示没有库存，清理排队信息
            if (sgoods==null){
                //则表示没有库存，清理排队信息
                clearUserQueue(username);
                return;
            }


            String time = seckillStatus.getTime();

            Long id= seckillStatus.getGoodsId();



            //查询秒杀商品
            String nameSpace = "SeckillGoods_"+time;
            SeckillGoods seckillGoods = (SeckillGoods)redisTemplate.boundHashOps(nameSpace).get(id);

            //判断有没有库存
            if (seckillGoods==null || seckillGoods.getStockCount()<=0){
                throw new RuntimeException("已售罄！");
            }


            //创建订单对象
            SeckillOrder seckillOrder = new SeckillOrder();

            //秒杀商品Id
            seckillOrder.setSeckillId(id);

            seckillOrder.setId(idWorker.nextId());

            //支付金额
            seckillOrder.setMoney(seckillGoods.getCostPrice());

            //用户
            seckillOrder.setUserId(username);

            //创建时间
            seckillOrder.setCreateTime(new Date());

            //状态   0  --- 未支付
            seckillOrder.setStatus("0");


            //将订单对象存储起来
            //1. 一个用户只能有一个未支付秒杀订单
            //2.订单存入Redis
            //  Hash
            //      namespace   SeckillOrder
            //                      username:SeckillOrder

            redisTemplate.boundHashOps("SeckillOrder").put(username,seckillOrder);

            /**
             * 库存递减
             * Redis.stockCount
             * 商品有可能是最后一个，如果是最后一个，则将Redis中商品信息删除，并且将Redis中该商品的数据同步到MySQL
             *
             */
            seckillGoods.setStockCount(seckillGoods.getStockCount()-1);

            if (seckillGoods.getStockCount()<=0){
                //同步数据到MySQL
                seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);

                //删除Redis中的商品数据
                redisTemplate.boundHashOps(nameSpace).delete(id);
            }else{
                //同步数据到Redis
                redisTemplate.boundHashOps(nameSpace).put(id,seckillGoods);
            }

            //更新下单状态
            seckillStatus.setOrderId(seckillOrder.getId());//id
            seckillStatus.setMoney(Float.valueOf(seckillGoods.getCostPrice()));

            //待付款
            redisTemplate.boundHashOps("UserQueueStatus").put(username,seckillStatus);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


    /**
     * 清理用户排队抢单信息
     */
    public void clearUserQueue(String username){
        //排队标识
        redisTemplate.boundHashOps("UserQueueCount").delete(username);

        //排队信息清理掉
        redisTemplate.boundHashOps("UserQueueStatus").delete(username);

    }
}
